package rad.framework.mda.jpagen.actions;

import rad.framework.mda.generator.Console;
import rad.framework.mda.jpagen.actions.BaseUtiltiyActionExtension.BaseUtilityAction;
import rad.framework.mda.util.ModelUtil;

import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Enumeration;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.PrimitiveType;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;

public class AddMaxLengthActionExtension extends
BaseUtiltiyActionExtension {

	protected static final String LENGTH = "org.hibernate.validator.Length";
	protected static final Integer MIN_LENGTH = 0;
	protected static final Integer MAX_LENGTH = 255;
	protected static final String MESSAGE_TEXT = "Max field length exceeded for %1s.";
	protected static final String MIN = "min";
	protected static final String MAX = "max";
	protected static final String MESSAGE = "message";
	
	public void fillContextMenu(IMenuManager aMenu) {
		getSubMenu(aMenu).add(new AddMaxLengthAction());
	}

	protected void execute(Class clazz) {
		EList<NamedElement> list = clazz.getMembers();
		for (NamedElement namedElement : list) {
			if (namedElement instanceof Property) {
				execute((Property) namedElement);
			}
		}
	}

	protected void execute(Property property) {
		if (isString(property) && !ModelUtil.isStereotypeApplied(property, LENGTH)) {
			setMaxLength(property);
			Console.getStream().println(
					"Set max length for - " + property.getQualifiedName());
		}
	}

	protected void setMaxLength(Property element) {
		Stereotype stereotype = (Stereotype) ModelUtil.getProfileElement(
				element, LENGTH);
		if (stereotype != null) {
			element.applyStereotype(stereotype);
			element.setValue(stereotype, MIN, MIN_LENGTH);
			element.setValue(stereotype, MAX, MAX_LENGTH);
			
			element.setValue(stereotype, MESSAGE, String.format(MESSAGE_TEXT, element.getName()));
		}
	}

	private boolean isString(Property property) {
		PrimitiveType type = getPrimitiveType(property, "String");
		return property.getType().equals(type);
	}
	
	private class AddMaxLengthAction extends BaseUtilityAction {
		private static final String LABEL = "Add Max String Length Stereotypes";

		public AddMaxLengthAction() {
			super(LABEL);
		}
	}
}
